/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package model.dao;

import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import model.pojo.Historico;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.transaction.UserTransaction;
import model.dao.exceptions.NonexistentEntityException;
import model.pojo.Aluno;
import model.pojo.Disciplina;
import model.pojo.Atividade;
import model.pojo.Turma;

/**
 *
 * @author leonidia
 */
public class AlunoJpaController implements AlunoInterface {

    public AlunoJpaController(UserTransaction utx, EntityManagerFactory emf) {
        this.utx = utx;
        this.emf = emf;
    }
    private UserTransaction utx = null;
    private EntityManagerFactory emf = null;

    @Override
    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    @Override
    public void create(Aluno aluno) {
        if (aluno.getHistorico() == null) {
            aluno.setHistorico(new ArrayList<Historico>());
        }
        if (aluno.getDisciplina() == null) {
            aluno.setDisciplina(new ArrayList<Disciplina>());
        }
        if (aluno.getAtividade() == null) {
            aluno.setAtividade(new ArrayList<Atividade>());
        }
        if (aluno.getTurma() == null) {
            aluno.setTurma(new ArrayList<Turma>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Collection<Historico> attachedHistorico = new ArrayList<Historico>();
            for (Historico historicoHistoricoToAttach : aluno.getHistorico()) {
                historicoHistoricoToAttach = em.getReference(historicoHistoricoToAttach.getClass(), historicoHistoricoToAttach.getId());
                attachedHistorico.add(historicoHistoricoToAttach);
            }
            aluno.setHistorico(attachedHistorico);
            Collection<Disciplina> attachedDisciplina = new ArrayList<Disciplina>();
            for (Disciplina disciplinaDisciplinaToAttach : aluno.getDisciplina()) {
                disciplinaDisciplinaToAttach = em.getReference(disciplinaDisciplinaToAttach.getClass(), disciplinaDisciplinaToAttach.getId());
                attachedDisciplina.add(disciplinaDisciplinaToAttach);
            }
            aluno.setDisciplina(attachedDisciplina);
            Collection<Atividade> attachedAtividade = new ArrayList<Atividade>();
            for (Atividade atividadeAtividadeToAttach : aluno.getAtividade()) {
                atividadeAtividadeToAttach = em.getReference(atividadeAtividadeToAttach.getClass(), atividadeAtividadeToAttach.getId());
                attachedAtividade.add(atividadeAtividadeToAttach);
            }
            aluno.setAtividade(attachedAtividade);
            Collection<Turma> attachedTurma = new ArrayList<Turma>();
            for (Turma turmaTurmaToAttach : aluno.getTurma()) {
                turmaTurmaToAttach = em.getReference(turmaTurmaToAttach.getClass(), turmaTurmaToAttach.getId());
                attachedTurma.add(turmaTurmaToAttach);
            }
            aluno.setTurma(attachedTurma);
            em.persist(aluno);
            for (Historico historicoHistorico : aluno.getHistorico()) {
                Aluno oldAlunoOfHistoricoHistorico = historicoHistorico.getAluno();
                historicoHistorico.setAluno(aluno);
                historicoHistorico = em.merge(historicoHistorico);
                if (oldAlunoOfHistoricoHistorico != null) {
                    oldAlunoOfHistoricoHistorico.getHistorico().remove(historicoHistorico);
                    oldAlunoOfHistoricoHistorico = em.merge(oldAlunoOfHistoricoHistorico);
                }
            }
            for (Disciplina disciplinaDisciplina : aluno.getDisciplina()) {
                disciplinaDisciplina.getAluno().add(aluno);
                disciplinaDisciplina = em.merge(disciplinaDisciplina);
            }
            for (Atividade atividadeAtividade : aluno.getAtividade()) {
                atividadeAtividade.getAluno().add(aluno);
                atividadeAtividade = em.merge(atividadeAtividade);
            }
            for (Turma turmaTurma : aluno.getTurma()) {
                turmaTurma.getAluno().add(aluno);
                turmaTurma = em.merge(turmaTurma);
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    @Override
    public void edit(Aluno aluno) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Aluno persistentAluno = em.find(Aluno.class, aluno.getId());
            Collection<Historico> historicoOld = persistentAluno.getHistorico();
            Collection<Historico> historicoNew = aluno.getHistorico();
            Collection<Disciplina> disciplinaOld = persistentAluno.getDisciplina();
            Collection<Disciplina> disciplinaNew = aluno.getDisciplina();
            Collection<Atividade> atividadeOld = persistentAluno.getAtividade();
            Collection<Atividade> atividadeNew = aluno.getAtividade();
            Collection<Turma> turmaOld = persistentAluno.getTurma();
            Collection<Turma> turmaNew = aluno.getTurma();
            Collection<Historico> attachedHistoricoNew = new ArrayList<Historico>();
            for (Historico historicoNewHistoricoToAttach : historicoNew) {
                historicoNewHistoricoToAttach = em.getReference(historicoNewHistoricoToAttach.getClass(), historicoNewHistoricoToAttach.getId());
                attachedHistoricoNew.add(historicoNewHistoricoToAttach);
            }
            historicoNew = attachedHistoricoNew;
            aluno.setHistorico(historicoNew);
            Collection<Disciplina> attachedDisciplinaNew = new ArrayList<Disciplina>();
            for (Disciplina disciplinaNewDisciplinaToAttach : disciplinaNew) {
                disciplinaNewDisciplinaToAttach = em.getReference(disciplinaNewDisciplinaToAttach.getClass(), disciplinaNewDisciplinaToAttach.getId());
                attachedDisciplinaNew.add(disciplinaNewDisciplinaToAttach);
            }
            disciplinaNew = attachedDisciplinaNew;
            aluno.setDisciplina(disciplinaNew);
            Collection<Atividade> attachedAtividadeNew = new ArrayList<Atividade>();
            for (Atividade atividadeNewAtividadeToAttach : atividadeNew) {
                atividadeNewAtividadeToAttach = em.getReference(atividadeNewAtividadeToAttach.getClass(), atividadeNewAtividadeToAttach.getId());
                attachedAtividadeNew.add(atividadeNewAtividadeToAttach);
            }
            atividadeNew = attachedAtividadeNew;
            aluno.setAtividade(atividadeNew);
            Collection<Turma> attachedTurmaNew = new ArrayList<Turma>();
            for (Turma turmaNewTurmaToAttach : turmaNew) {
                turmaNewTurmaToAttach = em.getReference(turmaNewTurmaToAttach.getClass(), turmaNewTurmaToAttach.getId());
                attachedTurmaNew.add(turmaNewTurmaToAttach);
            }
            turmaNew = attachedTurmaNew;
            aluno.setTurma(turmaNew);
            aluno = em.merge(aluno);
            for (Historico historicoOldHistorico : historicoOld) {
                if (!historicoNew.contains(historicoOldHistorico)) {
                    historicoOldHistorico.setAluno(null);
                    historicoOldHistorico = em.merge(historicoOldHistorico);
                }
            }
            for (Historico historicoNewHistorico : historicoNew) {
                if (!historicoOld.contains(historicoNewHistorico)) {
                    Aluno oldAlunoOfHistoricoNewHistorico = historicoNewHistorico.getAluno();
                    historicoNewHistorico.setAluno(aluno);
                    historicoNewHistorico = em.merge(historicoNewHistorico);
                    if (oldAlunoOfHistoricoNewHistorico != null && !oldAlunoOfHistoricoNewHistorico.equals(aluno)) {
                        oldAlunoOfHistoricoNewHistorico.getHistorico().remove(historicoNewHistorico);
                        oldAlunoOfHistoricoNewHistorico = em.merge(oldAlunoOfHistoricoNewHistorico);
                    }
                }
            }
            for (Disciplina disciplinaOldDisciplina : disciplinaOld) {
                if (!disciplinaNew.contains(disciplinaOldDisciplina)) {
                    disciplinaOldDisciplina.getAluno().remove(aluno);
                    disciplinaOldDisciplina = em.merge(disciplinaOldDisciplina);
                }
            }
            for (Disciplina disciplinaNewDisciplina : disciplinaNew) {
                if (!disciplinaOld.contains(disciplinaNewDisciplina)) {
                    disciplinaNewDisciplina.getAluno().add(aluno);
                    disciplinaNewDisciplina = em.merge(disciplinaNewDisciplina);
                }
            }
            for (Atividade atividadeOldAtividade : atividadeOld) {
                if (!atividadeNew.contains(atividadeOldAtividade)) {
                    atividadeOldAtividade.getAluno().remove(aluno);
                    atividadeOldAtividade = em.merge(atividadeOldAtividade);
                }
            }
            for (Atividade atividadeNewAtividade : atividadeNew) {
                if (!atividadeOld.contains(atividadeNewAtividade)) {
                    atividadeNewAtividade.getAluno().add(aluno);
                    atividadeNewAtividade = em.merge(atividadeNewAtividade);
                }
            }
            for (Turma turmaOldTurma : turmaOld) {
                if (!turmaNew.contains(turmaOldTurma)) {
                    turmaOldTurma.getAluno().remove(aluno);
                    turmaOldTurma = em.merge(turmaOldTurma);
                }
            }
            for (Turma turmaNewTurma : turmaNew) {
                if (!turmaOld.contains(turmaNewTurma)) {
                    turmaNewTurma.getAluno().add(aluno);
                    turmaNewTurma = em.merge(turmaNewTurma);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = aluno.getId();
                if (findAluno(id) == null) {
                    throw new NonexistentEntityException("The aluno with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    @Override
    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Aluno aluno;
            try {
                aluno = em.getReference(Aluno.class, id);
                aluno.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The aluno with id " + id + " no longer exists.", enfe);
            }
            Collection<Historico> historico = aluno.getHistorico();
            for (Historico historicoHistorico : historico) {
                historicoHistorico.setAluno(null);
                historicoHistorico = em.merge(historicoHistorico);
            }
            Collection<Disciplina> disciplina = aluno.getDisciplina();
            for (Disciplina disciplinaDisciplina : disciplina) {
                disciplinaDisciplina.getAluno().remove(aluno);
                disciplinaDisciplina = em.merge(disciplinaDisciplina);
            }
            Collection<Atividade> atividade = aluno.getAtividade();
            for (Atividade atividadeAtividade : atividade) {
                atividadeAtividade.getAluno().remove(aluno);
                atividadeAtividade = em.merge(atividadeAtividade);
            }
            Collection<Turma> turma = aluno.getTurma();
            for (Turma turmaTurma : turma) {
                turmaTurma.getAluno().remove(aluno);
                turmaTurma = em.merge(turmaTurma);
            }
            em.remove(aluno);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    @Override
    public List<Aluno> findAlunoEntities() {
        return findAlunoEntities(true, -1, -1);
    }

    @Override
    public List<Aluno> findAlunoEntities(int maxResults, int firstResult) {
        return findAlunoEntities(false, maxResults, firstResult);
    }

    private List<Aluno> findAlunoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Aluno as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    @Override
    public Aluno findAluno(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Aluno.class, id);
        } finally {
            em.close();
        }
    }

    @Override
    public int getAlunoCount() {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select count(o) from Aluno as o");
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
    @Override
    public boolean existeAluno(String cpf) {
        EntityManager em = getEntityManager();
        try {
            if (em.createQuery("Select cpf from Aluno where cpf = '" + cpf + "'").getResultList().isEmpty()){
                return false;
            } else {
                return true;
            }
        } finally {
            em.close();
        }
    }
    
}
